package com.tutou.ikuser.filter;


import cn.hutool.core.bean.BeanUtil;
import com.tutou.ikuser.pojo.po.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.tutou.ikuser.util.RedisConstants.LOGIN_TOKEN_KEY;
import static com.tutou.ikuser.util.RedisConstants.LOGIN_TOKEN_TTL;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static StringRedisTemplate stringRedisTemplate;

    @Autowired
    public void setRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        JwtAuthenticationFilter.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (!StringUtils.hasText(token)) {
            filterChain.doFilter(request, response);
            return;
        }
        try {
            Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(LOGIN_TOKEN_KEY + token);
            if (!userMap.isEmpty()) {
                User user = BeanUtil.copyProperties(userMap, User.class);
                token = LOGIN_TOKEN_KEY + token;
                stringRedisTemplate.expire(token, LOGIN_TOKEN_TTL, TimeUnit.MINUTES);
                //获取权限信息封装到authentication后存入SecurityContextHolder
                // 创建Authentication对象，设置用户名、密码、权限信息，如果不设置权限信息后面的认证过滤器会过滤没有权限的用户
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(user, null, null);
                // 将Authentication对象设置到SecurityContext中
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        } catch (Exception e) {
            // 处理JWT验证失败的情况
            SecurityContextHolder.clearContext(); // 清除认证信息
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "请登录~");
            return;
        }
        filterChain.doFilter(request, response);
    }
}
